package com.md.notes.fragment;

import android.os.Bundle;

import androidx.activity.OnBackPressedCallback;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.TextView;

import com.md.notes.R;
import com.md.notes.model.module.log.LoggerABC;
import com.md.notes.model.module.log.LoggerBuilder;
import com.md.notes.util.StringUtils;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.data.MutableDataSet;
import com.vladsch.flexmark.ext.tables.TablesExtension;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.MatchResult;


/**
 * A simple {@link Fragment} subclass.
 * Use the {@link ViewFragment#newInstance} factory method to
 * create an instance of this fragment.
 * <p>
 * 笔记的查看页面
 */
public class ViewFragment extends Fragment {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    public static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private TextView markdownView;
    private WebView webView;

    public ViewFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment ViewFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static ViewFragment newInstance(String param1, String param2) {
        ViewFragment fragment = new ViewFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_view, container, false);


        initView(view);
        initData();
        addListener();
        return view;
    }


    private void initView(View view) {
        webView = view.findViewById(R.id.webView);

        webView.getSettings().setAllowFileAccess(true);
        webView.getSettings().setAllowContentAccess(true);
        webView.getSettings().setJavaScriptEnabled(true);



    }

    private void initData() {
    }

    private void addListener() {

        // 注册返回键处理
        requireActivity().getOnBackPressedDispatcher().addCallback(
                getViewLifecycleOwner(), // LifecycleOwner会自动处理生命周期
                new OnBackPressedCallback(true) {
                    @Override
                    public void handleOnBackPressed() {
                        /*if (hasUnsavedChanges()) {
                        showExitConfirmDialog();
                        } else {
                        }*/
                        // 没有未保存的更改，直接返回
                        //setEnabled(false);
                        //requireActivity().getOnBackPressedDispatcher().onBackPressed();
                        // 设置结果并返回
                        finishWithResult();  // 调用这个方法
                    }
                }
        );
    }

    private void finishWithResult() {
        requireActivity().setResult(requireActivity().RESULT_OK);
        requireActivity().finish();
    }

    @Override
    @MainThread
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // 创建示例 Markdown 文本
        //String markdown = "# Hello World\n\n" +
        //                "这是一个 **Markdown** 测试。\n\n" +
        //                "* 列表项 1\n" +
        //                "* 列表项 2\n\n" +
        //                "[链接示例](https://www.example.com)";

        // 设置 flexmark-java 解析器选项
        MutableDataSet options = new MutableDataSet();
        options.set(Parser.EXTENSIONS, Arrays.asList(TablesExtension.create()));

        // 创建解析器
        Parser parser = Parser.builder(options).build();
        HtmlRenderer renderer = HtmlRenderer.builder(options).build();

        // 手动解析自定义语法
        String markdown = StringUtils.extractAfterDashes(mParam1);
        markdown = parseCustomContainers(markdown);
        markdown = parseTaskListItems(markdown); // 解析任务列表项
        markdown = parseDelItems(markdown);//替换删除线

        LoggerABC loggerABC = LoggerBuilder.build(requireActivity());
        // 将 Markdown 转换为 HTML
        String html = renderer.render(parser.parse(markdown));
        
        // 处理HTML中的标题标签，添加id属性
        html = processHeadingsWithId(html);
        
        // 获取外部存储根目录
        File rootDir = Environment.getExternalStorageDirectory();
        // 创建 MdNotes 文件夹
        File mdNotesDir = new File(rootDir, "MdNotes");

        String basePath ="file://" + mdNotesDir.getAbsolutePath() + "/";
        //img标签中的相对路径，替换成绝对路径
        html = replaceImgSrcBasePath(html, basePath);


        StringBuffer sbuffer = new StringBuffer();
        sbuffer.append("<!DOCTYPE html><html><head>");
        //sbuffer.append("<base href=\"file://" + mdNotesDir.getAbsolutePath() + "/\" />");
        sbuffer.append("<meta charset='UTF-8'>");
        sbuffer.append("<meta name='viewport' content='width=device-width, initial-scale=1.0'>");
        sbuffer.append("<style>");
        sbuffer.append("body { padding: 15px; font-family: system-ui; }");
        sbuffer.append(".custom-container.tip { margin: 1rem 0; padding: 0.5rem 1.5rem; border-radius: 8px; background-color: #e6f4ea; border: 1px solid #e6f4ea;display: flex;align-items: center;}");
        sbuffer.append(".custom-container-title.tip { font-weight: 600; margin-right: 0.5rem; color: #42b983;}");
        sbuffer.append(".custom-container.warning { margin: 1rem 0; padding: 0.5rem 1.5rem; border-radius: 8px; background-color: #FCF4DC; border: 1px solid #FCF4DC;display: flex;align-items: center;}");
        sbuffer.append(".custom-container-title.warning { font-weight: 600; margin-right: 0.5rem; color: #c28100;}");

        sbuffer.append(".custom-container.danger { margin: 1rem 0; padding: 0.5rem 1.5rem; border-radius: 8px; background-color: #FDE4E8; border: 1px solid #FDE4E8;display: flex;align-items: center;}");
        sbuffer.append(".custom-container-title.danger { font-weight: 600; margin-right: 0.5rem; color: #b8272c;}");

        sbuffer.append(".custom-container.info { margin: 1rem 0; padding: 0.5rem 1.5rem; border-radius: 8px; background-color: #DFF4FB; border: 1px solid #DFF4FB;display: flex;align-items: center;}");
        sbuffer.append(".custom-container-title.info { font-weight: 600; margin-right: 0.5rem; color: #2888A7;}");

        sbuffer.append(".custom-container.important { margin: 1rem 0; padding: 0.5rem 1.5rem; border-radius: 8px; background-color: #F1ECFC; border: 1px solid #F1ECFC;display: flex;align-items: center;}");
        sbuffer.append(".custom-container-title.important { font-weight: 600; margin-right: 0.5rem; color: #6F42C1;}");

        sbuffer.append(".custom-container.note { margin: 1rem 0; padding: 0.5rem 1.5rem; border-radius: 8px; background-color: #EFF0F3; border: 1px solid #EFF0F3;display: flex;align-items: center;}");
        sbuffer.append(".custom-container-title.note { font-weight: 600; margin-right: 0.5rem; color: #656869;}");

        sbuffer.append(".custom-container-content { color: #333;}");
        sbuffer.append("pre {background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto;}");
        //sbuffer.append("code {color: #d63384;}");
        sbuffer.append("table{border-collapse:collapse}table,td,th{border:1px solid black}");
        sbuffer.append("img {width: 100%;height: 100%;object-fit: cover;}");/* 或者 contain */
        sbuffer.append("blockquote{background-color:#f5f5f5;border-left:5px solid #007acc;padding:8px;font-family:monospace;white-space:pre-wrap}");
        sbuffer.append("a{text-decoration:none;}");
        sbuffer.append("</style>");
        sbuffer.append("<!-- 引入 Highlight.js 脚本 -->");
        sbuffer.append(String.format("<link rel=\"stylesheet\" href=\"%shighlight.js/11.8.0/default.min.css\">", basePath));
        sbuffer.append("</head><body>");
        sbuffer.append(html);
        sbuffer.append(String.format("<script src=\"%shighlight.js/11.8.0/highlight.min.js\"></script>", basePath));
        sbuffer.append(String.format("<script src=\"%shighlight.js/11.8.0/python.min.js\"></script>", basePath));
        sbuffer.append("<script>");
        sbuffer.append("// 高亮所有代码块");
        sbuffer.append("\r\n");
        sbuffer.append("hljs.highlightAll();");
        sbuffer.append("// 动态监听新增代码块（可选）");
        sbuffer.append("\r\n");
        sbuffer.append("const observer = new MutationObserver((mutations) => {");
        sbuffer.append("        mutations.forEach((mutation) => {");
        sbuffer.append("                mutation.addedNodes.forEach((node) => {");
        sbuffer.append("                   if (node.tagName === 'PRE' || node.tagName === 'CODE') {");
        sbuffer.append("                      hljs.highlightBlock(node);");
        sbuffer.append(                    "}");
        sbuffer.append("                 });");
        sbuffer.append("         });");
        sbuffer.append("});");
        sbuffer.append("// 监听整个文档的变化");
        sbuffer.append("\r\n");
        sbuffer.append("observer.observe(document.body, { childList: true, subtree: true });");
        sbuffer.append("</script>");
        sbuffer.append("</body></html>");
        String fullHtml = sbuffer.toString();
        loggerABC.logMessage(LoggerABC.DEBUG, fullHtml);
        // 在 WebView 中显示渲染后的 HTML
        webView.loadDataWithBaseURL(null, fullHtml, "text/html", "UTF-8", null);
    }

    @Override
    public void onDestroy() {

        super.onDestroy();
    }

    private String parseCustomContainers(String markdown) {
        // 使用正则表达式替换自定义容器语法
        markdown = markdown.replaceAll("::: tip\\s*\\n([\\s\\S]*?)\\n:::", "<div class='custom-container tip'><span class=\"custom-container-title tip\">提示</span><div class=\"custom-container-content\">$1</div></div>");

        markdown = markdown.replaceAll("::: warning\\s*\\n([\\s\\S]*?)\\n:::", "<div class='custom-container warning'><span class=\"custom-container-title warning\">注意</span><div class=\"custom-container-content\">$1</div></div>");
        markdown = markdown.replaceAll("::: danger\\s*\\n([\\s\\S]*?)\\n:::", "<div class='custom-container danger'><span class=\"custom-container-title danger\">警告</span><div class=\"custom-container-content\">$1</div></div>");
        markdown = markdown.replaceAll("::: info\\s*\\n([\\s\\S]*?)\\n:::", "<div class='custom-container info'><span class=\"custom-container-title info\">相关信息</span><div class=\"custom-container-content\">$1</div></div>");
        markdown = markdown.replaceAll("::: important\\s*\\n([\\s\\S]*?)\\n:::", "<div class='custom-container important'><span class=\"custom-container-title important\">重要</span><div class=\"custom-container-content\">$1</div></div>");
        markdown = markdown.replaceAll("::: note\\s*\\n([\\s\\S]*?)\\n:::", "<div class='custom-container note'><span class=\"custom-container-title note\">注</span><div class=\"custom-container-content\">$1</div></div>");
        // 可以添加更多的自定义语法解析
        return markdown;
    }

    private String parseTaskListItems(String markdown) {
        // 使用正则表达式替换任务列表项
        markdown = markdown.replaceAll("- \\[ \\] (.+)", "<input type='checkbox' disabled> $1 <br>");
        markdown = markdown.replaceAll("- \\[x\\] (.+)", "<input type='checkbox' checked disabled> $1 <br>");
        return markdown;
    }

    private String parseDelItems(String markdown) {
        markdown = markdown.replaceAll("~~([^~]+)~~", "<del>$1</del>");
        return markdown;
    }

    //====================

        /**
     * 处理HTML中的标题标签，为其添加id属性
     * @param html 原始HTML字符串
     * @return 处理后的HTML字符串
     */
    private String processHeadingsWithId(String html) {
        // 匹配h1-h3标签的正则表达式
        String regex = "<h([1-3])>(.*?)</h\\1>";
        StringBuilder result = new StringBuilder(html);
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(regex);
        java.util.regex.Matcher matcher = pattern.matcher(html);
        
        // 用于记录找到的所有匹配项
        List<MatchResult> matches = new ArrayList<>();
        while (matcher.find()) {
            matches.add(matcher.toMatchResult());
        }
        
        // 从后向前替换，避免位置偏移问题
        for (int i = matches.size() - 1; i >= 0; i--) {
            MatchResult match = matches.get(i);
            String level = match.group(1);
            String content = match.group(2);
            
            // 生成ID
            String id = generateHeadingId(content);
            
            // 构建新的标签
            String replacement = String.format("<h%s id=\"%s\">%s</h%s>",
                level, id, content, level);
                
            // 替换原文本
            result.replace(match.start(), match.end(), replacement);
        }
        
        return result.toString();
    }

    /**
     * 根据标题内容生成ID
     * @param content 标题内容
     * @return 处理后的ID字符串
     */
    private String generateHeadingId(String content) {
        // 1. 转换为小写
        String id = content.toLowerCase();
        
        // 2. 移除HTML标签
        id = id.replaceAll("<[^>]+>", "");
        
        // 3. 移除中文标点符号
        id = id.replaceAll("[，。！？、；：“” ''（）【】《》〈〉「」『』〔〕…—～]", "");
        
        // 4. 将空格替换为横杠
        id = id.replaceAll("\\s+", "-");
        
        // 5. 处理多个连续的横杠
        id = id.replaceAll("-+", "-");
        
        // 6. 移除首尾的横杠
        id = id.replaceAll("^-|-$", "");
        
        return id;
    }

    /**
     * 将HTML字符串中所有img标签的src属性中的"./"替换为指定的绝对路径
     *
     * @param html      输入的HTML字符串
     * @param basePath  替换的目标绝对路径，例如 "https://example.com/images/"
     * @return 修改后的HTML字符串
     */
    public static String replaceImgSrcBasePath(String html, String basePath) {
        if (html == null || html.isEmpty() || basePath == null || basePath.isEmpty()) {
            return html; // 如果输入为空，直接返回原字符串
        }

        // 定义正则表达式匹配img标签的src属性值
        String regex = "(<img[^>]*\\bsrc\\s*=\\s*['\"])(\\.\\/)([^'\"]*)";
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(regex);
        java.util.regex.Matcher matcher = pattern.matcher(html);

        // 使用 StringBuffer 来存储替换后的结果
        StringBuffer result = new StringBuffer();

        while (matcher.find()) {
            // 将匹配到的 "./" 替换为指定的 basePath
            String replacement = matcher.group(1) + basePath + matcher.group(3);
            matcher.appendReplacement(result, java.util.regex.Matcher.quoteReplacement(replacement));
        }

        // 将剩余部分追加到结果中
        matcher.appendTail(result);

        return result.toString();
    }

}